package cCommand

import (
	"fmt"
	"os"
	"strings"

	"gitee.com/csingo/cLog"
)

const help = `
usage : %s command [ --param=xxx ] ...

commands :

%s
`

func exec() {
	if len(os.Args) == 1 || !command_config.CommandLine {
		return
	}

	cLog.WithContext(nil, map[string]any{
		"source": "cCommand.exec",
	}, []cLog.Option{
		cLog.IncludePaths{},
	}).Trace("进入 command line 模式")
	defer cLog.WithContext(nil, map[string]any{
		"source": "cCommand.exec",
	}, []cLog.Option{
		cLog.IncludePaths{},
	}).Fatalln("退出 command line 模式")

	executor := os.Args[0]
	command := os.Args[1]
	params := make([]string, 0)
	commandTips := make([]string, 0)
	commands := make(map[string]string)
	runners := make(map[string]*CommandConf_Command)
	length := 0

	for app, item := range container.commands {
		for cmd, item2 := range item {
			for method, param := range item2 {
				index := fmt.Sprintf(command_name_format, app, cmd, method)
				if length < len(index) {
					length = len(index)
				}
				commands[index] = param
				runners[index] = &CommandConf_Command{
					Mode:    CommandMode_Line,
					Instant: true,
					Wait:    0,
					Try:     1,
					Cron:    "* * * * * *",
					App:     app,
					Command: cmd,
					Method:  method,
				}
			}
		}
	}

	for k, v := range commands {
		format := fmt.Sprintf("%%-%ds%%s", length+8)
		item := fmt.Sprintf(format, k, v)
		commandTips = append(commandTips, item)
	}

	tips := fmt.Sprintf(help, executor, strings.Join(commandTips, "\n"))

	if len(os.Args) > 2 {
		for _, argument := range os.Args[2:] {
			if strings.HasPrefix(argument, "--param=") {
				params = append(params, strings.TrimPrefix(argument, "--param="))
			}
		}
	}

	var runner *CommandConf_Command
	var ok bool
	if runner, ok = runners[command]; !ok {
		cLog.WithContext(nil, map[string]any{
			"source":  "cCommand.exec",
			"command": command,
		}, []cLog.Option{
			cLog.IncludePaths{},
		}).Error("命令不存在")
		fmt.Println(tips)
		return
	}

	runner.Options = params
	err := run(runner)
	if err != nil {
		cLog.WithContext(nil, map[string]any{
			"source":  "cCommand.exec",
			"command": runner,
			"err":     err.Error(),
		}, []cLog.Option{
			cLog.IncludePaths{},
		}).Error("命令执行失败")
	}

}
